home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / AppsToGo / Kibitz / DoCursor.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-22  |  6.6 KB  |  254 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        docursor.c
  5. ** Written by:  Eric Soldan
  6. **
  7. ** Copyright © 1990-1992 Apple Computer, Inc.
  8. ** All rights reserved. */
  9.  
  10.  
  11.  
  12. /*****************************************************************************/
  13.  
  14.  
  15.  
  16. #include "Kibitz.h"                /* Get the Kibitz includes/typedefs, etc.    */
  17. #include "KibitzCommon.h"        /* Get the stuff in common with rez.        */
  18. #include "Kibitz.protos"        /* Get the prototypes for Kibitz.            */
  19.  
  20. #ifndef __OSEVENTS__
  21. #include <OSEvents.h>
  22. #endif
  23.  
  24. #ifndef __TEXTEDITCONTROL__
  25. #include <TextEditControl.h>
  26. #endif
  27.  
  28. #ifndef __TOOLUTILS__
  29. #include <ToolUtils.h>
  30. #endif
  31.  
  32. #ifndef __UTILITIES__
  33. #include <Utilities.h>
  34. #endif
  35.  
  36.  
  37.  
  38. /*****************************************************************************/
  39.  
  40.  
  41.  
  42. RgnHandle    gCurrentCursorRgn;
  43.     /* The current cursor region.  The initial cursor region is an empty
  44.     ** region, which will cause WaitNextEvent to generate a mouse-moved
  45.     ** event, which will cause us to set the cursor for the first time. */
  46.  
  47. Cursor    *gCurrentCursor, **gCurrentCursorHndl;
  48.     /* The current cursor that applies to gCurrentCursorRgn.  These values
  49.     ** are here to shorten the re-processing time for determining the
  50.     ** correct cursor after an event.  This is specifically so that characters
  51.     ** can be typed into the TextEdit control faster.  If we spend a great
  52.     ** deal of time per-event recalculating the cursor region, text entry for
  53.     ** the TextEdit control slows down considerably.  If you want to override
  54.     ** the time savings because you are changing the cursor directly, either
  55.     ** set gCurrentCursor to nil, or call DoSetCursor to set the cursor.
  56.     ** DoSetCursor simply sets gCurrentCursor to nil, as well as setting
  57.     ** the cursor. */
  58.  
  59.  
  60.  
  61. /*****************************************************************************/
  62. /*****************************************************************************/
  63.  
  64. #ifdef applec
  65. #pragma segment DoCursor
  66. #endif
  67.  
  68. /*****************************************************************************/
  69. /*****************************************************************************/
  70.  
  71.  
  72.  
  73. /* Handle the cursor changes, based on if an AppleEvent is involved, or
  74. ** depending on the location of the cursor.  This also calculates the region
  75. ** where the current cursor resides (for WaitNextEvent).  If the mouse is
  76. ** ever outside of that region, an event would be generated, causing this
  77. ** function to be called, allowing us to change the region to the region
  78. ** the mouse is currently in.  The only other cursor management in this sample
  79. ** is for operations such as pulling down a menu.  Just prior to pulling down
  80. ** the menu, the arrow cursor is set.  This prevents any latencies in cursor
  81. ** update to cause a non-arrow cursor to be used in the menus.  This technique
  82. ** should be carried throughout the application. */
  83.  
  84. void    DoCursor(void)
  85. {
  86.     WindowPtr    window, oldPort;
  87.     WindowPeek    wpeek;
  88.     RgnHandle    rgn1, rgn2, rgn3;
  89.     Rect        boardRct, structRct, teViewRct;
  90.     Point        mouseLoc;
  91.     FileRecHndl    frHndl;
  92.     FileRecPtr    frPtr;
  93.     TEHandle    teHndl;
  94.     Boolean        readOnly, twoPlayer, canMove;
  95.     short        resync, myColor, moveColor;
  96.     EventRecord    option;
  97.  
  98.     mouseLoc = GetGlobalMouse();
  99.  
  100.     if ((!gInBackground) && (!IsDAWindow(window = FrontWindow()))) {
  101.  
  102.         if (IsAppWindow(window)) {
  103.  
  104.             if (gCurrentCursor) {
  105.                 if (PtInRgn(mouseLoc, gCurrentCursorRgn)) {
  106.                     SetCursor(*gCurrentCursorHndl);
  107.                     return;
  108.                 }
  109.             }
  110.  
  111.             SetEmptyRgn(gCurrentCursorRgn);
  112.             GetPort(&oldPort);
  113.  
  114.             if (CTETargetInfo(&teHndl, &teViewRct) == window) {
  115.                 SetPort(window);
  116.                 SectRect(&teViewRct, &(window->portRect), &teViewRct);
  117.                 LocalToGlobalRect(&teViewRct);
  118.                 SetPort(oldPort);
  119.                 RectRgn(gCurrentCursorRgn, &teViewRct);
  120.                 if (PtInRect(mouseLoc, &teViewRct)) {
  121.                     SetCursor(gCurrentCursor = *(gCurrentCursorHndl = GetCursor(ibeamCursor)));
  122.                     return;
  123.                 }
  124.             }
  125.  
  126.             rgn1 = NewRgn();
  127.             rgn2 = NewRgn();
  128.             rgn3 = NewRgn();
  129.  
  130.             wpeek = (WindowPeek)window;
  131.             for (; wpeek; wpeek = wpeek->nextWindow) {
  132.  
  133.                 if (IsAppWindow((WindowPtr)wpeek)) {
  134.  
  135.                     frHndl = (FileRecHndl)GetWRefCon((WindowPtr)wpeek);
  136.                     frPtr  = *frHndl;
  137.                     readOnly  = frPtr->fileState.readOnly;
  138.                     twoPlayer = frPtr->doc.twoPlayer;
  139.                     resync    = frPtr->doc.resync;
  140.                     myColor   = frPtr->doc.myColor;
  141.                     moveColor = WhosMove(frHndl);
  142.  
  143.                     OSEventAvail(nullEvent, &option);
  144.                     if (option.modifiers & optionKey)
  145.                         if (myColor != kMessageDoc) myColor = moveColor;
  146.  
  147.                     canMove = true;
  148.  
  149.                     if (readOnly)
  150.                         canMove = false;
  151.                     if ((twoPlayer) && (myColor != moveColor))
  152.                         canMove = false;
  153.                     if (myColor == kMessageDoc)
  154.                         canMove = false;
  155.                     if (GameStatus(frHndl) != kGameContinues)
  156.                         canMove = false;
  157.                     if ((moveColor == WHITE) && ((*frHndl)->doc.compMovesWhite))
  158.                         canMove = false;
  159.                     if ((moveColor == BLACK) && ((*frHndl)->doc.compMovesBlack))
  160.                         canMove = false;
  161.                     if ((resync == kScrolling) || (resync == kResync))
  162.                         canMove = false;
  163.  
  164.                     if (canMove) {
  165.                         boardRct = GlobalBoardRect((WindowPtr)wpeek);
  166.                         RectRgn(rgn1, &boardRct);
  167.                         DiffRgn(rgn1, rgn2, rgn1);
  168.                         UnionRgn(rgn3, rgn1, rgn3);
  169.                     }
  170.                 }
  171.  
  172.                 structRct = GetWindowStructureRect((WindowPtr)wpeek);
  173.                 RectRgn(rgn1, &structRct);
  174.                 UnionRgn(rgn1, rgn2, rgn2);
  175.             }        /* Assume cursor is over an app content. */
  176.  
  177.             if (!PtInRgn(mouseLoc, rgn3)) {
  178.                     /* The cursor wasn't over a chessboard after all. */
  179.                 SetRectRgn(rgn1, kExtremeNeg, kExtremeNeg,
  180.                                  kExtremePos, kExtremePos);
  181.                 DiffRgn(rgn1, rgn3, rgn3);
  182.                 gCurrentCursor     = &qd.arrow;
  183.                 gCurrentCursorHndl = &gCurrentCursor;
  184.                 SetCursor(gCurrentCursor);
  185.             }
  186.             else SetCursor(*(gCurrentCursorHndl = GetCursor(handCursor)));
  187.  
  188.             DiffRgn(rgn3, gCurrentCursorRgn, gCurrentCursorRgn);
  189.  
  190.             DisposeRgn(rgn1);
  191.             DisposeRgn(rgn2);
  192.             DisposeRgn(rgn3);
  193.             return;
  194.         }
  195.  
  196.         else DoSetCursor(&qd.arrow);
  197.     }
  198.  
  199.     else {
  200.         SetRectRgn(gCurrentCursorRgn, kExtremeNeg, kExtremeNeg,
  201.                                       kExtremePos, kExtremePos);
  202.         gCurrentCursor = nil;
  203.     }
  204. }
  205.  
  206.  
  207.  
  208. /*****************************************************************************/
  209.  
  210.  
  211.  
  212. void    DoSetCursor(Cursor *cursor)
  213. {
  214.     if (cursor) SetCursor(cursor);
  215.     gCurrentCursor = nil;
  216.     if (!cursor) DoCursor();
  217. }
  218.  
  219.  
  220.  
  221. /*****************************************************************************/
  222.  
  223.  
  224.  
  225. Rect    BoardRect(void)
  226. {
  227.     Rect    boardRct;
  228.  
  229.     SetRect(&boardRct, kBoardHOffset + 1, kBoardVOffset + 1,
  230.              kBoardHOffset + 8 * kBoardSqSize + 1,
  231.              kBoardVOffset + 8 * kBoardSqSize + 1);
  232.     return(boardRct);
  233. }
  234.  
  235.  
  236.  
  237. /*****************************************************************************/
  238.  
  239.  
  240.  
  241. Rect    GlobalBoardRect(WindowPtr window)
  242. {
  243.     Rect    boardRct, windRct;
  244.  
  245.     boardRct = BoardRect();
  246.     windRct  = GetWindowContentRect(window);
  247.  
  248.     OffsetRect(&boardRct, windRct.left, windRct.top);
  249.     return(boardRct);
  250. }
  251.  
  252.  
  253.  
  254.